package com.hhf.springboot.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhf.springboot.common.ErrorCode;
import com.hhf.springboot.constant.CommonConstant;
import com.hhf.springboot.exception.BusinessException;
import com.hhf.springboot.exception.ThrowUtils;
import com.hhf.springboot.mapper.CommentMapper;
import com.hhf.springboot.mapper.CommentThumbMapper;
import com.hhf.springboot.model.dto.comment.CommentQueryRequest;
import com.hhf.springboot.model.entity.*;
import com.hhf.springboot.model.enums.CommentTypeEnum;
import com.hhf.springboot.model.vo.CommentVO;
import com.hhf.springboot.model.vo.UserVO;
import com.hhf.springboot.service.BisheProjectService;
import com.hhf.springboot.service.CommentService;
import com.hhf.springboot.service.PostService;
import com.hhf.springboot.service.UserService;
import com.hhf.springboot.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 帖子服务实现
 *
 * @author hhf
 * @data 2024/9/26
 */
@Service
@Slf4j
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Resource
    private UserService userService;

    @Resource
    private PostService postService;

    @Resource
    private BisheProjectService bisheProjectService;

    @Resource
    private CommentThumbMapper commentThumbMapper;


    @Override
    public void validComment(Comment comment, boolean add) {
        if (comment == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String content = comment.getContent();
        Long targetId = comment.getTargetId();
        String type = comment.getType();
        // 创建时，参数不能为空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(type, content, targetId.toString()), ErrorCode.PARAMS_ERROR);
        }
        // 有参数则校验
        if (StringUtils.isNotBlank(content) && content.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长");
        }
        CommentTypeEnum commentTypeEnum = CommentTypeEnum.getEnumByValue(type);
        if (StringUtils.isNotBlank(type) && commentTypeEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论类型不正确");
        }
        //查询评论的target是否存在
        switch (commentTypeEnum){
            case POST -> {
                Post post = postService.getById(targetId);
                if (post == null){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "目标不存在");
                }
            }
            case PROJECT -> {
                BisheProject project = bisheProjectService.getById(targetId);
                if (project == null){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "目标不存在");
                }
            }
            case SERVICE -> {
                // TODO 未来添加
            }
        }

    }

    /**
     * 获取查询包装类
     *
     * @param commentQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Comment> getQueryWrapper(CommentQueryRequest commentQueryRequest) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        if (commentQueryRequest == null) {
            return queryWrapper;
        }
        String searchText = commentQueryRequest.getSearchText();
        String sortField = commentQueryRequest.getSortField();
        String sortOrder = commentQueryRequest.getSortOrder();
        Long id = commentQueryRequest.getId();
        String content = commentQueryRequest.getContent();
        Long userId = commentQueryRequest.getUserId();
        Long parentId = commentQueryRequest.getParentId();
        Long notId = commentQueryRequest.getNotId();
        Long targetId = commentQueryRequest.getTargetId();
        String type = commentQueryRequest.getType();
        // 拼接查询条件
        if (StringUtils.isNotBlank(searchText)) {
            queryWrapper.and(qw -> qw.like("title", searchText).or().like("content", searchText));
        }
        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
        queryWrapper.ne(ObjectUtils.isNotEmpty(notId), "id", notId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "user_id", userId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(parentId), "parent_id", parentId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(targetId), "target_id", targetId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(type), "type", type);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                StrUtil.toUnderlineCase(sortField));
        return queryWrapper;
    }

    @Override
    public CommentVO getCommentVO(Comment comment, HttpServletRequest request) {
        CommentVO commentVO = CommentVO.objToVo(comment);
        long commentId = comment.getId();
        // 1. 关联查询用户信息
        Long userId = comment.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
        }
        UserVO userVO = userService.getUserVO(user);
        commentVO.setUser(userVO);
        // 2. 已登录，获取用户点赞、收藏状态
        User loginUser = userService.getLoginUserPermitNull(request);
        if (loginUser != null) {
            // 获取点赞
            QueryWrapper<CommentThumb> commentThumbQueryWrapper = new QueryWrapper<>();
            commentThumbQueryWrapper.in("comment_id", commentId);
            commentThumbQueryWrapper.eq("user_id", loginUser.getId());
            CommentThumb commentThumb = commentThumbMapper.selectOne(commentThumbQueryWrapper);
            commentVO.setHasThumb(commentThumb != null);
        }
        return commentVO;
    }

    @Override
    public Page<CommentVO> getCommentVOPage(Page<Comment> commentPage, HttpServletRequest request) {
        List<Comment> commentList = commentPage.getRecords();
        Page<CommentVO> commentVOPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        if (CollUtil.isEmpty(commentList)) {
            return commentVOPage;
        }
        // 1. 关联查询用户信息
        Set<Long> userIdSet = commentList.stream().map(Comment::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 已登录，获取用户点赞、收藏状态
        Map<Long, Boolean> commentIdHasThumbMap = new HashMap<>();
        Map<Long, Boolean> commentIdHasFavourMap = new HashMap<>();
        User loginUser = userService.getLoginUserPermitNull(request);
        if (loginUser != null) {
            Set<Long> commentIdSet = commentList.stream().map(Comment::getId).collect(Collectors.toSet());
            loginUser = userService.getLoginUser(request);
            // 获取点赞
            QueryWrapper<CommentThumb> commentThumbQueryWrapper = new QueryWrapper<>();
            commentThumbQueryWrapper.in("comment_id", commentIdSet);
            commentThumbQueryWrapper.eq("user_id", loginUser.getId());
            List<CommentThumb> commentCommentThumbList = commentThumbMapper.selectList(commentThumbQueryWrapper);
            commentCommentThumbList.forEach(commentCommentThumb -> commentIdHasThumbMap.put(commentCommentThumb.getCommentId(), true));
        }
        // 填充信息
        List<CommentVO> commentVOList = commentList.stream().map(comment -> {
            CommentVO commentVO = CommentVO.objToVo(comment);
            Long userId = comment.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            commentVO.setUser(userService.getUserVO(user));
            commentVO.setHasThumb(commentIdHasThumbMap.getOrDefault(comment.getId(), false));
            return commentVO;
        }).collect(Collectors.toList());
        commentVOPage.setRecords(commentVOList);
        return commentVOPage;
    }

    @Override
    public Page<CommentVO> getCommentVOParentPage(Page<Comment> commentPage, HttpServletRequest request) {
        List<Comment> commentList = commentPage.getRecords();
        Page<CommentVO> commentVOPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        if (CollUtil.isEmpty(commentList)) {
            return commentVOPage;
        }
        //获取父评论
        List<Comment> parentCommentList = commentPage.getRecords().stream().filter((comment -> comment.getParentId() == -1)).collect(Collectors.toList());
        //获取子评论
        List<Comment> childrenCommentList = this.list().stream().filter((comment -> comment.getParentId() != -1)).collect(Collectors.toList());


        // 1. 关联查询用户信息
        Set<Long> userIdSet = commentList.stream().map(Comment::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 已登录，获取用户点赞状态
        Map<Long, Boolean> commentIdHasThumbMap = new HashMap<>();
        User loginUser = userService.getLoginUserPermitNull(request);
        if (loginUser != null) {
            Set<Long> commentIdSet = commentList.stream().map(Comment::getId).collect(Collectors.toSet());
            loginUser = userService.getLoginUser(request);
            // 获取点赞
            QueryWrapper<CommentThumb> commentThumbQueryWrapper = new QueryWrapper<>();
            commentThumbQueryWrapper.in("comment_id", commentIdSet);
            commentThumbQueryWrapper.eq("user_id", loginUser.getId());
            List<CommentThumb> commentCommentThumbList = commentThumbMapper.selectList(commentThumbQueryWrapper);
            commentCommentThumbList.forEach(commentCommentThumb -> commentIdHasThumbMap.put(commentCommentThumb.getCommentId(), true));
        }
        // 3. 获取子评论信息
        Map<Long, List<Comment>> commentIdChildrenListMap = childrenCommentList.stream().collect(Collectors.groupingBy(Comment::getParentId));

        // 填充信息
        List<CommentVO> commentVOList = parentCommentList.stream().map(comment -> {
            CommentVO commentVO = CommentVO.objToVo(comment);
            Long userId = comment.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            commentVO.setUser(userService.getUserVO(user));
            commentVO.setHasThumb(commentIdHasThumbMap.getOrDefault(comment.getId(), false));

            //填充子评论信息
            List<Comment> collectComment = commentIdChildrenListMap.getOrDefault(comment.getId(), List.of());
            if (!collectComment.isEmpty()){
                List<CommentVO> collect = collectComment.stream().map((item-> getCommentVO(item,request))).collect(Collectors.toList());
                commentVO.setChildrenList(collect);
            } else {
                commentVO.setChildrenList(List.of());
            }
            return commentVO;
        }).collect(Collectors.toList());
        commentVOPage.setRecords(commentVOList);
        return commentVOPage;
    }

    @Override
    public Page<Comment> getCommentPage(Page<Comment> commentPage) {
        List<Comment> commentPageList = commentPage.getRecords();
        Page<Comment> commentPage2 = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        if (CollUtil.isEmpty(commentPageList)) {
            return commentPage2;
        }
        // 对象列表 => 封装对象列表
        List<Comment> commentPageList2 = commentPageList.stream().map(comment -> {
            comment.setPictureList(JSONUtil.toList(comment.getPictures(), String.class));
            return comment;
        }).collect(Collectors.toList());

        //其它操作


        commentPage2.setRecords(commentPageList2);
        return commentPage2;
    }


}




